package com.dify.tool.service.impl;

import cn.hutool.core.text.StrPool;
import cn.hutool.core.util.IdUtil;
import cn.hutool.json.JSONObject;
import com.dify.tool.common.utils.DocTemplateUtils;
import com.dify.tool.common.utils.MinioUtil;
import com.dify.tool.common.utils.MoneyToChineseUtil;
import com.dify.tool.service.IToolService;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.xwpf.usermodel.*;
import org.springframework.ai.tool.annotation.Tool;
import org.springframework.ai.tool.annotation.ToolParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * <p>
 * 代码生成业务表 服务实现类
 * </p>
 *
 * @author shl
 * @since 2025-06-03
 */
@Slf4j
@Service
public class ToolServiceImpl implements IToolService {

    @Autowired
    private MinioUtil minioUtil;

    @Value("${minio.public-prefix}")
    private String publicPrefix;

    @Value("${minio.endpoint}")
    private String endpoint;


    @Autowired
    private DocTemplateUtils docTemplateUtils;

    @Override
    @Tool(name = "leave", description = "生成请假单")
    public String leave(Map<String, Object> params) {
        return new JSONObject(params).toString();
    }

    @Override
    @Tool(name = "business", description = "生成出差单")
    public String business(Map<String, Object> params) {
        return new JSONObject(params).toString();

    }

    @Tool(name = "contract", description = "生成合同")
    public String contract(
            @ToolParam(description = "styleTitleProjectName") String styleTitleProjectName,
            @ToolParam(description = "contentProjectName") String contentProjectName,
            @ToolParam(description = "purchaseContent") String purchaseContent,
            @ToolParam(description = "projectAddress") String projectAddress,
            @ToolParam(description = "constructionDemand") String constructionDemand,
            @ToolParam(description = "purchaseAmount") String purchaseAmount,
            @ToolParam(description = "performanceAmount") String performanceAmount,
            @ToolParam(description = "responseFileTime") String responseFileTime,
            @ToolParam(description = "contacts") String contacts,
            @ToolParam(description = "contactNumber") String contactNumber,
            @ToolParam(description = "email") String email,
            @ToolParam(description = "purchaseDate") String purchaseDate,
            @ToolParam(description = "method1") String method1,
            @ToolParam(description = "method2") String method2) {
        Resource resource = new ClassPathResource("contractTemplate.docx");
        Map<String, String> params = new HashMap<>();
        params.put("styleTitleProjectName", styleTitleProjectName);
        params.put("contentProjectName", contentProjectName);
        params.put("purchaseContent", purchaseContent);
        params.put("projectAddress", projectAddress);
        params.put("constructionDemand", constructionDemand);
        params.put("purchaseAmount", purchaseAmount);
        params.put("performanceAmount", performanceAmount);
        params.put("responseFileTime", responseFileTime);
        params.put("contacts", contacts);
        params.put("contactNumber", contactNumber);
        params.put("email", email);
        params.put("purchaseDate", purchaseDate);
        params.put("method1", method1);
        params.put("method2", method2);
        String fileName = IdUtil.objectId() + StrPool.DOT + "docx";
        log.info("合同生成开始：{}", params);
        return processDocument(resource, fileName, params);
    }

    @Override
    @Tool(name = "legalRepresentativeInformation", description = "生成法定代表人身份证明或法定代表人授权委托书")
    public String legalRepresentativeInformation(Map<String, String> params) {
        Resource resource = new ClassPathResource("legalRepresentativeInformation.docx");
        String fileName = IdUtil.objectId() + StrPool.DOT + "docx";
        return processDocument(resource, fileName, params);
    }

    @Override
    @Tool(name = "competeStatement", description = "生成竞争比选响应声明书")
    public String competeStatement(Map<String, String> params) {
        // 报价金额转为中文大写
        String quoteAmountChinese = MoneyToChineseUtil.toChinese(new BigDecimal(params.get("quoteAmount")));
        params.put("quoteAmountChinese", quoteAmountChinese);
        Resource resource = new ClassPathResource("competeStatement.docx");
        String fileName = IdUtil.objectId() + StrPool.DOT + "docx";
        return processDocument(resource, fileName, params);
    }

    @Override
    @Tool(name = "quoteOtherInfo", description = "生成报价人其它资料")
    public String quoteOtherInfo(Map<String, String> params) {
        Resource resource = new ClassPathResource("quoteOtherInfo.docx");
        String fileName = IdUtil.objectId() + StrPool.DOT + "docx";
        return processDocument(resource, fileName, params);
    }

    /**
     * 处理整个文档
     */
    private String processDocument(Resource resource, String fileName, Map<String, String> params) {
        File outputFile = null;
        try (InputStream inputStream = resource.getInputStream();
             XWPFDocument doc = new XWPFDocument(inputStream)) {
            // 处理普通段落
            for (XWPFParagraph paragraph : doc.getParagraphs()) {
                processParagraph(paragraph, params);
            }
            // 处理所有表格
            for (XWPFTable table : doc.getTables()) {
                processTable(table, params);
            }
            // 保存到临时文件
            outputFile = File.createTempFile(UUID.randomUUID().toString(), ".docx");
            try (FileOutputStream out = new FileOutputStream(outputFile)) {
                doc.write(out);
            }
            // 上传到minio
            try (FileInputStream fileInputStream = new FileInputStream(outputFile)) {
                String path = docTemplateUtils.genFileKey(fileName);
                String url = minioUtil.uploadFileAndGetObject(fileInputStream, path, null);
                return url.replace(endpoint, publicPrefix);
            } catch (Exception e) {
                log.error("", e);
            }
        } catch (Exception e) {
            log.error("生成文件失败：{}", e);
        } finally {
            if (outputFile.exists()) {
                if (!outputFile.delete()) {
                    log.error("临时文件删除失败: " + outputFile.getAbsolutePath());
                }
            }
        }
        return "";
    }

    /**
     * 处理段落
     */
    private void processParagraph(XWPFParagraph paragraph, Map<String, String> params) {
        String text = paragraph.getText();
        if (text == null || text.isEmpty()) {
            return;
        }

        for (Map.Entry<String, String> entry : params.entrySet()) {
            String placeholder = "${" + entry.getKey() + "}";
            if (text.contains(placeholder)) {
                replaceTextWithStyle(paragraph, placeholder, entry.getValue());
                continue;
            }
        }
    }

    /**
     * 处理表格
     */
    private void processTable(XWPFTable table, Map<String, String> params) {
        for (XWPFTableRow row : table.getRows()) {
            for (XWPFTableCell cell : row.getTableCells()) {
                for (XWPFParagraph paragraph : cell.getParagraphs()) {
                    processParagraph(paragraph, params);
                }
            }
        }
    }

    /**
     * 替换文本并设置样式
     */
    private void replaceTextWithStyle(XWPFParagraph paragraph, String placeholder, String newText) {
        // 替换原有内容
        for (XWPFRun run : paragraph.getRuns()) {
            String text = run.getText(0);
            if (text != null && text.contains(placeholder)) {
                // 只替换匹配到的部分，保留其他内容
                text = text.replace(placeholder, newText);
                run.setText(text, 0);
            }
        }
    }

}
